#ifndef FF_PLATFORM_DYNAMIC_LIBRARY_POSIX_H
#define FF_PLATFORM_DYNAMIC_LIBRARY_POSIX_H

#include <string>

namespace FF::Platform {

enum class LibraryLoadPolicy : uint8_t
{
    GLOBAL,
    LAZY,
    LOCAL
};

class DynamicLibrary final {
public:
    DynamicLibrary() = default;

    DynamicLibrary(DynamicLibrary const &) = delete;
    DynamicLibrary &operator= (DynamicLibrary const &) = delete;

    DynamicLibrary(DynamicLibrary &&) = delete;
    DynamicLibrary &operator= (DynamicLibrary &&) = delete;

    ~DynamicLibrary() = default;

    // The method returns true if success. Otherwise the method returns false.
    [[nodiscard]] bool Load(char const *path, LibraryLoadPolicy policy) noexcept;

    [[nodiscard]] bool IsLoaded() const noexcept;

    // The method returns true if success. Otherwise the method returns false.
    [[nodiscard]] bool Unload() noexcept;

    // The method returns a pointer to function if success. Otherwise the methods returns nullptr.
    [[nodiscard]] void *GetFunction(char const *name) const noexcept;

private:
    void *handle_ = nullptr;
    std::string name_{};
};

} // namespace FF::Platform

#endif // FF_PLATFORM_DYNAMIC_LIBRARY_POSIX_H
